//
//  SlidingTabHeaderView.swift
//  suda
//
//  Created by youai on 2019/8/30.
//  Copyright © 2019 youi. All rights reserved.
//

import Foundation
import UIKit

class SlidingTabTitle : UIButton {
    static let normalFont = UIFont.systemFont(ofSize: 14)
    static let selectedFont = UIFont.systemFont(ofSize: 14, weight: .medium)
    init(title:String,frame:CGRect,numberOfLines:Int){
        super.init(frame: frame)
        setTitle(title, for: .normal)
        setTitleColor(.x333333, for: .normal)
        setTitleColor(.xFC4C02, for: .selected)
        titleLabel?.font = SlidingTabTitle.normalFont
        titleLabel?.textAlignment = .center
        titleLabel?.numberOfLines = numberOfLines
        titleLabel?.minimumScaleFactor = 7
    }
    override var isSelected: Bool {
        didSet{
            if isSelected {
                titleLabel?.font = SlidingTabTitle.selectedFont
            }else{
                titleLabel?.font = SlidingTabTitle.normalFont
            }
        }
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
class SlidingTabHeaderScrollView : UIScrollView ,UIScrollViewDelegate {
    //定义一个闭包类型
    typealias selBlock = (_ index:Int) -> Void
    //声明一个变量
    var selBtnBack: selBlock?
    //定义一个方法,方法的参数为和swiftBlock类型一致的闭包,并赋值给callBack
    func callSelBlock(block: @escaping selBlock) {
        selBtnBack = block
    }
    
    var buttons = [SlidingTabTitle]()
    let bottomIndicator = UIView()
    let leftSpace : CGFloat
    let titleSpace : CGFloat
    weak var scrollView : SlidingTabScrollView? = nil
    
    init(screenWidth:CGFloat, height:CGFloat,titles:[String],titleSpace:CGFloat,leftSpace:CGFloat,autoTitleWidth:Bool=false,selectedIndex:Int=0) {
        self.titleSpace = titleSpace
        self.leftSpace = leftSpace
        super.init(frame: .init(x: 0, y: 0, width: screenWidth, height: height))
        var lastLeft : CGFloat = 10
        for (idx,title) in titles.enumerated() {
            let frame : CGRect
            if autoTitleWidth {
                let titleSize = title.size(withAttributes: [.font: SlidingTabTitle.selectedFont])
                var titleSpace_ = titleSize.width + 15//(titleSize.width + 10 < titleSpace) ? titleSpace : (titleSize.width + 10)
                if titleSpace_ < titleSpace * 0.75 {
                   titleSpace_ = titleSpace * 0.75
                }
                
                frame = CGRect(x: lastLeft, y: 0, width: titleSpace_, height: height)
                lastLeft = lastLeft + titleSpace_
            }else{
                frame = CGRect(x: leftSpace+(idx.cgFloat()*titleSpace), y: 0, width: titleSpace, height: height)
            }
            let button = SlidingTabTitle(title: title,frame:frame,numberOfLines: autoTitleWidth ? 1 : 2 )
            buttons.append(button)
            addSubview(button)
            button.addTarget(self, action: #selector(onTitleSelected(button:)), for: .touchUpInside)
            button.layer.anchorPoint = .init(x: 0.5, y: 0.5)
            self.contentSize = CGSize(width: frame.maxX + leftSpace, height: height)
            self.showsHorizontalScrollIndicator = false
            self.showsVerticalScrollIndicator = false
        }
        self.backgroundColor = .white
        
        self.addSubview(bottomIndicator)
        bottomIndicator.backgroundColor = .xFC4C02
        bottomIndicator.bounds = .init(x: 0, y: 0, width: 64, height: 2)
        _onTitleSelected(button: buttons[selectedIndex])
    }
    
    func _onTitleSelected(button:SlidingTabTitle){
        var selectedIdx : Int = -1
        for (idx,b) in buttons.enumerated() {
            if b == button {
                b.isSelected = true
                selectedIdx = idx
            }else{
                b.isSelected = false
            }
        }
        bottomIndicator.center = CGPoint(x: button.center.x, y: self.bounds.height-1)
//        scrollView?.contentOffset = CGPoint(x: selectedIdx.cgFloat() * (scrollView?.bounds.width ?? 0), y: 0)
        judgeSwitchPage(nextIndex: selectedIdx.cgFloat())
        
        if selBtnBack != nil{
            selBtnBack!(selectedIdx)
        }
        self.scrollRectToVisible(button.frame, animated: true)
    }
    
    @objc func onTitleSelected(button:SlidingTabTitle){
        UIView.animate(withDuration: 0.3) {
            self._onTitleSelected(button:button)
        }
    }
    private var lastPage : CGFloat = 0.0
    var lastPageIdx : Int {
        get{
            return Int(lastPage)
        }
    }
    func judgeSwitchPage(nextIndex:CGFloat){
        let next = nextIndex.rounded()
        if next != lastPage {
            lastPage = next
            let nextIdx = Int(next)
            for (idx,b) in buttons.enumerated() {
                b.isSelected = (idx == nextIdx)
            }
            onPageChanged?(nextIdx)
        }
    }
    var onPageChanged : ((Int)->Void)? = nil
    
    func scrollViewDidScroll(_ scrollView: UIScrollView){
        let width = scrollView.bounds.width
        if width <= 0 {
            return
        }
        let offset = scrollView.contentOffset.x / width
        bottomIndicator.center = CGPoint(x: leftSpace+titleSpace*offset , y: self.bounds.height-1)
    }
    var recordDragEnding : Bool = false
    func scrollViewWillBeginDragging(_ scrollView: UIScrollView){
        recordDragEnding = true
    }
    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool){
        if recordDragEnding && (!decelerate) {
            //处理当前位置
            if scrollView.bounds.width > 0 {
                let idx = scrollView.contentOffset.x / scrollView.bounds.width
                judgeSwitchPage(nextIndex: idx)
            }
            recordDragEnding = false
        }
    }
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView){
        if recordDragEnding{
            //处理当前位置
            if scrollView.bounds.width > 0 {
                let idx = scrollView.contentOffset.x / scrollView.bounds.width
                judgeSwitchPage(nextIndex: idx)
            }
            recordDragEnding = false
        }
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

class SlidingTabHeaderView : UIView ,UIScrollViewDelegate {
    //定义一个闭包类型
    typealias selBlock = (_ index:Int) -> Void
    //声明一个变量
    var selBtnBack: selBlock?
    //定义一个方法,方法的参数为和swiftBlock类型一致的闭包,并赋值给callBack
    func callSelBlock(block: @escaping selBlock) {
        selBtnBack = block
    }
    
    var buttons = [SlidingTabTitle]()
    let bottomIndicator = UIView()
    let leftSpace : CGFloat
    let titleSpace : CGFloat
    weak var scrollView : SlidingTabScrollView? = nil
    
    init(screenWidth:CGFloat, height:CGFloat,titles:[String],titleSpace:CGFloat) {
        self.titleSpace = titleSpace
        leftSpace = (screenWidth - titleSpace * (titles.count-1).cgFloat())*0.5
        super.init(frame: .init(x: 0, y: 0, width: screenWidth, height: height))
        for (idx,title) in titles.enumerated() {
            let frame = CGRect(x: leftSpace+((idx.cgFloat()-0.5)*titleSpace), y: 0, width: titleSpace, height: height)
            let button = SlidingTabTitle(title: title,frame:frame,numberOfLines: 2)
            buttons.append(button)
            addSubview(button)
            button.addTarget(self, action: #selector(onTitleSelected(button:)), for: .touchUpInside)
            button.layer.anchorPoint = .init(x: 0.5, y: 0.5)
        }
        self.backgroundColor = .white
        
        self.addSubview(bottomIndicator)
        bottomIndicator.backgroundColor = .xFC4C02
        bottomIndicator.bounds = .init(x: 0, y: 0, width: 64, height: 2)
        _onTitleSelected(button: buttons[0])
    }
    
    func _onTitleSelected(button:SlidingTabTitle){
        var selectedIdx : Int = -1
        for (idx,b) in buttons.enumerated() {
            if b == button {
                b.isSelected = true
                selectedIdx = idx
            }else{
                b.isSelected = false
            }
        }
        bottomIndicator.center = CGPoint(x: button.center.x, y: self.bounds.height-1)
        scrollView?.contentOffset = CGPoint(x: selectedIdx.cgFloat() * (scrollView?.bounds.width ?? 0), y: 0)
        judgeSwitchPage(nextIndex: selectedIdx.cgFloat())
        
        if selBtnBack != nil{
            selBtnBack!(selectedIdx)
        }
    }
    
    @objc func onTitleSelected(button:SlidingTabTitle){
        UIView.animate(withDuration: 0.3) {
            self._onTitleSelected(button:button)
        }
    }
    private var lastPage : CGFloat = 0.0
    var lastPageIdx : Int {
        get{
            return Int(lastPage)
        }
    }
    func judgeSwitchPage(nextIndex:CGFloat){
        let next = nextIndex.rounded()
        if next != lastPage {
            lastPage = next
            let nextIdx = Int(next)
            for (idx,b) in buttons.enumerated() {
                b.isSelected = (idx == nextIdx)
            }
            onPageChanged?(nextIdx)
        }
    }
    var onPageChanged : ((Int)->Void)? = nil
    
    func scrollViewDidScroll(_ scrollView: UIScrollView){
        let width = scrollView.bounds.width
        if width <= 0 {
            return
        }
        let offset = scrollView.contentOffset.x / width
        bottomIndicator.center = CGPoint(x: leftSpace+titleSpace*offset , y: self.bounds.height-1)
    }
    var recordDragEnding : Bool = false
    func scrollViewWillBeginDragging(_ scrollView: UIScrollView){
        recordDragEnding = true
    }
    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool){
        if recordDragEnding && (!decelerate) {
            //处理当前位置
            if scrollView.bounds.width > 0 {
                let idx = scrollView.contentOffset.x / scrollView.bounds.width
                judgeSwitchPage(nextIndex: idx)
            }
            recordDragEnding = false
        }
    }
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView){
        if recordDragEnding{
            //处理当前位置
            if scrollView.bounds.width > 0 {
                let idx = scrollView.contentOffset.x / scrollView.bounds.width
                judgeSwitchPage(nextIndex: idx)
            }
            recordDragEnding = false
        }
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

class SlidingTabScrollView : UIScrollView {
    let contentView = UIView()
    var pages = [UIView]()
    weak var tabHeader : SlidingTabHeaderView? = nil{
        didSet{
            self.delegate = tabHeader
        }
    }
    init(screenWidth:CGFloat, tabCount:Int) {
        super.init(frame: .zero)
        addSubview(contentView)
        contentView.snp.makeConstraints { (make) in
            make.edges.equalToSuperview()
            make.height.equalToSuperview()
        }
        var lastPage : UIView? = nil
        for _ in 0..<tabCount {
            let page = UIView()
            pages.append(page)
            contentView.addSubview(page)
            page.snp.makeConstraints { (make) in
                make.top.bottom.equalToSuperview()
                if lastPage == nil {
                    make.left.equalToSuperview()
                }else{
                    make.left.equalTo(lastPage!.snp.right)
                }
                make.width.equalTo(screenWidth)
            }
            lastPage = page
            
        }
        lastPage!.snp.makeConstraints { (make) in
            make.right.equalToSuperview()
        }
        self.isPagingEnabled = true
    }
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
